package com.tiger.cloud.common.redis;

import java.util.List;

import javax.annotation.PostConstruct;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Transaction;

/**
 * 类名称: [JedisOperation]<br/>
 * 创建人: [GaoNan]<br/>
 * 创建时间: [2015年10月10日 下午1:51:12]<br/>
 * 修改人: [GaoNan]<br/>
 * 修改时间: [2015年10月10日 下午1:51:12]<br/>
 * 备注:[] 修改备注: [说明本次修改内容]<br/>
 * 版本: [v1.0]<br/>
 */
public class RedisTemplate extends AbstractRedisOperation {

	private JedisPool jedisPool;

	@PostConstruct
	public void init() {
		jedisPool = new JedisPool();
	}

	public RedisTemplate() {
	}

	public RedisTemplate(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}

	@Override
	public List<String> gets(final String... keys) {
		return exec0(new JedisCallback<List<String>>() {
			@Override
			public List<String> doCallback(Jedis jedis) {
				return jedis.mget(keys);
			}
		});
	}

	@Override
	public String sets(final String... keyvalues) {
		return exec0(new JedisCallback<String>() {
			@Override
			public String doCallback(Jedis jedis) {
				return jedis.mset(keyvalues);
			}
		});
	}

	@Override
	public Long del(final String... keys) {
		return exec0(new JedisCallback<Long>() {
			@Override
			public Long doCallback(Jedis jedis) {
				return jedis.del(keys);
			}
		});
	}

	@Override
	public List<Object> transaction(final TransactionCallback callback) {
		return exec0(new JedisCallback<List<Object>>() {
			@Override
			public List<Object> doCallback(Jedis jedis) {
				Transaction trans = jedis.multi();
				callback.doCallback(trans);
				return trans.exec();
			}
		});
	}

	public void pipelined(final PiplineCallback callback) {
		exec0(new JedisCallback<Void>() {
			@Override
			public Void doCallback(Jedis jedis) {
				Pipeline pipeline = jedis.pipelined();
				callback.doCallback(pipeline);
				pipeline.sync();
				return null;
			}
		});
	}

	protected <T> T exec0(final JedisCallback<T> callback) {
		return exec(new RedisCallback<T>() {
			@Override
			public T doCallback(Jedis param) {
				return callback.doCallback(param);
			}
		});
	}

	@Override
	public <T> T exec(final RedisCallback<T> callback) {
		T t = null;
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			t = callback.doCallback(jedis);
		} catch (Exception e) {
			throw new KeyValueStoreException("", e);
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return t;
	}

	private interface JedisCallback<V> {
		V doCallback(Jedis jedis);
	}

	@Override
	public Long setNX(String key, String value) {
		return exec0(new JedisCallback<Long>() {
			@Override
			public Long doCallback(Jedis jedis) {
				return jedis.setnx(key, value);
			}
		});
	}

	@Override
	public String getSet(String key, String value) {
		return exec0(new JedisCallback<String>() {
			@Override
			public String doCallback(Jedis jedis) {
				return jedis.getSet(key, value);
			}
		});
	}
}
